#ifndef __CPU_USAGE__
#define __CPU_USAGE__

#ifdef _WIN64 || _WIN32
#include <windows.h>  
#include <psapi.h>  
#include <assert.h>  
#include <thread>
#include <functional>
#include <atlstr.h>

#endif

#ifdef linux
#include<iostream> 
#include "unistd.h"
#include<unistd.h>
#include<fcntl.h>
#include<ctype.h>
#include <sys/types.h>   
#include <dirent.h>
#include <errno.h>
#include <assert.h>

using namespace std; 
#endif

#include <list>
#include<stdlib.h>
#include<string.h>
#include <string>
#include <vector>
#include<stdio.h>
#include <mutex>

class CProcessMonitor { 
#ifdef _WIN64 || _WIN32

public:
	typedef enum {
		STATUS_LOGGING,  //  正在记录
		STATUS_STARTING, // 启动中
		STATUS_STOP,    // 停止记录
	}LOG_STATUS;

	typedef std::function<void (float)>  OnCpuAlert; // cpu告警
	typedef std::function<void (uint64_t,uint64_t)>  OnMemoryAlert; // 内存告警

	typedef struct {
		std::string time;
		float cpu;
		uint64_t phsical_memory;
		uint64_t virtual_memory;
	}ProcessStatus; // 某一个时刻的进程状态
	std::list<ProcessStatus *> &Logs();
	CProcessMonitor(DWORD ProcessID);
	CProcessMonitor();
	~CProcessMonitor();
	//返回值为进程句柄，可判断OpenProcess是否成功
	HANDLE SetPID(DWORD ProcessID);
	//-1 即为失败或进程已退出； 如果成功，首次调用会返回-2（中途用setpid更改了PID后首次调用也会返回-2）
 	float GetCpuUsage();  
	int GetMemoryUsage(uint64_t* mem, uint64_t* vmem);
	int StartLog(uint64_t milisecond);
	int StopLog();
	int SetAlert(bool);
	int SetAlertThreshold(int cpu, uint64_t mem,uint64_t mem2);
	// 设置内存报警的回调函数
	int SetMemoryAlertNotify(OnMemoryAlert );  
	// 设置cpu报警的回调函数
	int SetCpuAlertNotify(OnCpuAlert );
	friend void MonitorProcess(CProcessMonitor *,uint64_t );
private:
	std::list<ProcessStatus*> m_logs;
	LOG_STATUS m_log_status;
	uint64_t m_virtual_memory_threshold;
	uint64_t m_physical_memory_threshold;
	int m_cpu_threshold;
	OnMemoryAlert m_on_memory_alert;
	OnCpuAlert m_on_cpu_alert;
	bool m_alert;
	std::mutex m_mux;
	std::thread *m_thread;
 	typedef long long          int64_t;
 	typedef unsigned long long uint64_t;
	HANDLE _hProcess;  
	int _processor;    //cpu数量  
	int64_t _last_time;         //上一次的时间  
	int64_t _last_system_time;  
 
	// 时间转换  
	uint64_t FileTime2UTC(const FILETIME* ftime);
	// 获得CPU的核数  
	int get_processor_number();
	//初始化
	void init()
	{
		_last_system_time = 0;
		_last_time = 0;
		_hProcess = 0;
	}
	//  开始记录进程使用状态日志
 
	//关闭进程句柄
	void clear()
	{
		if (_hProcess) {
			CloseHandle(_hProcess);
			_hProcess = 0;
		}
	}
 
#endif

#ifdef linux
public:
	CProcessMonitor(uint16_t ProcessID) { 
		m_process_id = ProcessID;
		m_cpu_count = 0;
		m_cpu_count = sysconf( _SC_NPROCESSORS_CONF);
		m_enable_cpu_count = sysconf(_SC_NPROCESSORS_ONLN);
		printf("system cpu num is %d\n", sysconf( _SC_NPROCESSORS_CONF));
		printf("system enable cpu num is %d\n", sysconf(_SC_NPROCESSORS_ONLN));
	}
	float GetCpuUsage();
	float GetMemoryUsage();

	CProcessMonitor() {  

	}

	~CProcessMonitor() { 

	}	

private:
	uint16_t m_cpu_count; 
	uint16_t m_process_id;
	uint16_t m_enable_cpu_count; 

#endif

};

#endif